﻿namespace JoinBox.Forms;

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

// c#事件检查剪贴板 Clipboard
// https://www.cnblogs.com/crwy/p/11257725.html

/// <summary>
/// 更新剪贴板内容时提供通知
/// </summary>
public sealed class ClipboardNotification
{
    public const int WM_CLIPBOARDUPDATE = 0x031D;

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool AddClipboardFormatListener(IntPtr hWnd);
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool RemoveClipboardFormatListener(IntPtr hWnd);

    /// <summary>
    /// 更新剪贴板的内容时发生
    /// </summary>
    public event MethodInvoker? ClipboardUpdate;

    public ClipboardNotification()
    {
        _ = new NotificationForm(OnClipboardUpdate);
    }

    /// <summary>
    /// 提高了 <see cref="ClipboardUpdate"/> 事件.
    /// </summary>
    private void OnClipboardUpdate()
    {
        ClipboardUpdate?.Invoke();
    }

    /// <summary>
    /// 用于接收 WM_CLIPBOARDUPDATE 消息的隐藏表单。
    /// </summary>
    private class NotificationForm : Form
    {
#pragma warning disable IDE0052 // 删除未读的私有成员
        readonly MethodInvoker? _onClipboardUpdate;
#pragma warning restore IDE0052 // 删除未读的私有成员
        readonly IntPtr _hWnd;

        public NotificationForm(MethodInvoker? onClipboardUpdate)
        {
            _hWnd = this.Handle;
            AddClipboardFormatListener(_hWnd);

            _onClipboardUpdate = onClipboardUpdate;
        }

        ~NotificationForm()
        {
            RemoveClipboardFormatListener(this._hWnd);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_CLIPBOARDUPDATE)// 执行复制成功
            {
                try
                {
                    string str = DataFormats.Text;
                    str = DataFormats.OemText;
                    str = DataFormats.MetafilePict;    // 图元文件Pict
                    str = DataFormats.EnhancedMetafile;// 增强型图元文件
                    str = DataFormats.Bitmap;          // 位图
                    str = DataFormats.Dib;             // 设备无关的位图 这个还有信息

                    if (Clipboard.ContainsAudio())
                    {

                    }
                    else if (Clipboard.ContainsData(str))
                    {
                        var s = Clipboard.GetData(str);
                        MessageBox.Show(str); // 获取视口信息,但是这里截获不到啊
                    }
                    else if (Clipboard.ContainsFileDropList())
                    {

                    }
                    else if (Clipboard.ContainsImage())
                    {

                    }
                    else if (Clipboard.ContainsText())// 复制文本成功
                    {
                        string strdata = Clipboard.GetText();// 获取文本信息
                        if (strdata.StartsWith("http://") || strdata.StartsWith("https://"))
                        {
                            MessageBox.Show(string.Format("在{0}剪贴板发生了变化。\r\n" +
                               "包含URI：{1}" +
                               "\r\n---------------------------------------------\r\n",
                               DateTime.Now.ToString("HH:mm:ss"),
                               strdata));

                            // 返回0表示已经处理消息
                            m.Result = IntPtr.Zero;
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
            else
            {
                base.WndProc(ref m);
            }
        }
    }
}


#if false
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;

namespace ClipboardEdit
{
public class InterceptKeys
{
    private const int WH_KEYBOARD_LL = 13;

    private const int WM_KEYDOWN = 0x0100;

    static LowLevelKeyboardProc _proc = HookCallback;

    static IntPtr _hookID = IntPtr.Zero;

    /// <summary>
    /// 启动监测程序
    /// </summary>
    public static void RunHook()
    {
        _hookID = SetHook(_proc);
    }

    /// <summary>
    /// 关闭监测程序
    /// </summary>
    public static void UnHook()
    {
        UnhookWindowsHookEx(_hookID);
    }

    static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())// 当前程序acad
        using (ProcessModule curModule = curProcess.MainModule) // acad.exe
        {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
        }
    }

    /// <summary>
    /// 设置默认值与数据
    /// </summary>
    /// <param name="initInt"></param>
    /// <param name="outString">"F:\图片\精品分类\品牌图片\google徽标\@_@.gif"</param>
    public static void Init(int initInt, string outString)
    {
        i   = initInt;
        str = outString;
    }

    static int i = 0;
    static string str = @"I:\over\Images\google\@_@.jpg";

    static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            Keys key = (Keys)vkCode;
            // 同时按下Ctrl+V键的时候
            if (Control.ModifierKeys == Keys.Control && key.Equals(Keys.V))
            {
                // 获得剪切板数据
                string data = Clipboard.GetText(TextDataFormat.UnicodeText);
                // 重新设置剪切板数据
                DataObject m_data = new DataObject();
                m_data.SetData(DataFormats.Text, true, str.Replace("@_@", Convert.ToString(++i)));
                Clipboard.SetDataObject(m_data, true);
            }
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

#region 调用API

    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    static extern IntPtr SetWindowsHookEx(int idHook,

    LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    [return: MarshalAs(UnmanagedType.Bool)]

    static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,

    IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    static extern IntPtr GetModuleHandle(string lpModuleName);

#endregion
}
}
#endif



